/*****************************************************************************
 * gtkmm.cc : Gtkmmm interface
 ****************************************************************************
 * Copyright © 2006-2008 the VideoLAN team
 *
 * Authors: David GUGLIELMI <raxxx.fr@gmail.com>
 *          David LARROQUE <snio.fr@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include <gtkmm/calendar.h>
#include <gtkmm/main.h>
#include <gtkmm/window.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef HAVE_X11_XLIB_H
#include <X11/Xlib.h>
#endif

#include <assert.h>

#include "gtkmm.hh"
#include "main_interface.hh"

#include "../../../share/vlc32x32.xpm"
#include "../../../share/vlc32x32-christmas.xpm"

#include <vlc_plugin.h>
#include <vlc_window.h>

static int  Open        (vlc_object_t*);
static void Close       (vlc_object_t*);
static int  OpenDialogs (vlc_object_t*);
static int  WindowOpen  (vlc_object_t*);
static void WindowClose (vlc_object_t*);
static void Run         (intf_thread_t*);
static void Init        (intf_thread_t*);
static void ShowDialog  (intf_thread_t*, int, int, intf_dialog_args_t*);

vlc_module_begin ();

  set_shortname ("Gtkmm");
  set_description (_("Gtkmm interface"));
  set_category (CAT_INTERFACE);
  set_subcategory (SUBCAT_INTERFACE_MAIN);
  set_capability ("interface", 151);
  set_callbacks (Open, Close);

  add_shortcut ("gtkmm");

  add_submodule ();
    set_description (_("Gtkmm dialogs provider"));
    set_capability ("dialogs provider", 51);

    set_callbacks (OpenDialogs, Close);
/*
  add_submodule ();
    set_capability ("vout window", 50);
    set_callbacks (OpenDialogs, Close);
*/
vlc_module_end ();

static int
Open (vlc_object_t *p_this)
{

  intf_thread_t *p_intf = (intf_thread_t *)p_this;

#if defined HAVE_X11_XLIB_H
  Display *display = XOpenDisplay (NULL);
  if (!display)
   {
    msg_Err (p_intf, "Could not connect to X server");
    return VLC_EGENERIC;
   }
  XCloseDisplay (display);
#endif

  p_intf->p_sys = (intf_sys_t*)malloc (sizeof (intf_sys_t));
  if (!p_intf->p_sys)
   {
    msg_Err (p_intf, "Out of memory");
    return VLC_ENOMEM;
   }
  memset (p_intf->p_sys, 0, sizeof (intf_sys_t));

  p_intf->pf_run = Run;

  p_intf->p_sys->p_playlist = pl_Yield (p_intf);
  p_intf->p_sys->p_sub = msg_Subscribe (p_intf);

  var_Create (p_this, "window_widget", VLC_VAR_ADDRESS);

  return VLC_SUCCESS;
  
}

static int
OpenDialogs (vlc_object_t *p_this)
{

  intf_thread_t *p_intf = (intf_thread_t *)p_this;

  int val = Open (p_this);
  if (val)
    return val;

  p_intf->pf_show_dialog = ShowDialog;
  
  return VLC_SUCCESS;

}

static void
Run (intf_thread_t *p_intf)
{

  if (p_intf->pf_show_dialog)
   {
    if (vlc_thread_create (p_intf, "Gtkmm dialogs", Init, 0, true))
      msg_Err (p_intf, "failed to create Gtkmm dialogs thread");
   }
  else
    Init (p_intf);

}

static void
Init (intf_thread_t *p_intf)
{

  int argc = 1;
  char *args[] = {(char*)"", NULL};
  char **argv  = args;

  Gtk::Main app (argc, argv);

  Glib::Date date;
  Gtk::Calendar ().get_date (date);

  if (date.get_day_of_year () >= 354)
    Gtk::Window::set_default_icon (Gdk::Pixbuf::create_from_xpm_data (vlc_christmas_xpm));
  else
     Gtk::Window::set_default_icon (Gdk::Pixbuf::create_from_xpm_data (vlc_xpm));

  if( !p_intf->pf_show_dialog )
   {
    MainInterface *p_mi = new MainInterface (p_intf);
    p_intf->p_sys->p_mi = p_mi;
    p_mi->show_all ();    
   }
  else
    vlc_thread_ready (p_intf);

  p_intf->pf_show_dialog = ShowDialog;

  app.run ();
  
  delete p_intf->p_sys->p_mi;

}

static void
Close (vlc_object_t *p_this)
{

  intf_thread_t *p_intf = (intf_thread_t *)p_this;

  vlc_object_lock( p_intf );
  p_intf->b_dead = true;
  vlc_object_unlock( p_intf );

  vlc_object_lock (p_intf);
    p_intf->b_dead = true;
  vlc_object_unlock (p_intf);

#if 0
  if( p_intf->p_sys->b_isDialogProvider )
  {
    /* FIXME: Need to implante Dialog Provider EXIT event */
    vlc_thread_join( p_intf );
  }
#endif

  vlc_object_release (p_intf->p_sys->p_playlist);
  msg_Unsubscribe (p_intf, p_intf->p_sys->p_sub);

  free (p_intf->p_sys);

}

/* Callback to show a dialog *************************************************/

static void
ShowDialog (intf_thread_t *p_intf, int i_dialog_event, int i_arg, intf_dialog_args_t *p_arg)
{

  (void)p_intf;
  (void)i_dialog_event;
  (void)i_arg;
  (void)p_arg;

}

static int
WindowOpen (vlc_object_t *obj)
{

  vout_window_t *wnd = (vout_window_t *)obj;
  intf_thread_t *intf = \
  (intf_thread_t *) vlc_object_find_name (obj, "gtkmm", FIND_ANYWHERE);

  if (intf == NULL)
    return VLC_EGENERIC;

  assert (intf->i_object_type == VLC_OBJECT_INTF);
  var_Create (intf, "window_widget", VLC_VAR_ADDRESS);

}

static void
WindowClose (vlc_object_t *obj)
{
}
